package metier;

import ihm.Jeu;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import model.Behaviour;
import model.CharacterParameters;
import model.Difficulty;
import model.Dimension;
import model.GWParameters;
import model.Grid;
import model.ObjectRepresentation;
import model.Position;
import model.Sound;
import model.Sprite;
import model.SpriteSequence;
import model.actions.Action;
import model.actions.ChangeRepresentationAction;
import model.actions.GameOverAction;
import model.actions.IncrementDeathAction;
import model.actions.IncrementScoreAction;
import model.actions.MoveAction;
import model.actions.PlaySoundAction;
import model.actions.RemoveObjectAction;
import model.conditions.CharacterTouchCondition;
import model.conditions.DeathCondition;
import model.conditions.PositionCondition;
import model.conditions.RepresentationCondition;
import model.conditions.ScoreCondition;

public class GameState extends Observable {
	private GWParameters parameters;
	private Objet personnage;
	private ArrayList<Objet> objects;
	private Integer scoreValue = 0;
	private Integer deathValue = 0;
	private Boolean finished = false;
	private long gameTimeMs = 0;
	private long enemyAppearanceInterval;
	private HashMap<Objet, ArrayList<Action>> actionsToCommit = new HashMap<Objet, ArrayList<Action>>();
	private Observer jeu;

	public GameState(GWParameters parameters) {
		super();
		this.parameters = parameters;
	}

	public void init() {
		gameTimeMs = 0;
		scoreValue = 0;
		deathValue = 0;
		enemyAppearanceInterval = (long) (parameters.getDifficulty()
				.getEnemyAppearanceInterval() * 1000);
		personnage = parameters.getCharacterParameters().generateObject();
		objects = new ArrayList<Objet>();
	}

	public void controlLeft() {
		Position pos = personnage.getPosition();
		Dimension borders = parameters.getCharacterParameters()
				.getMovementBordersDimension();
		int column = pos.getColumn() - 1;
		int minColumn = borders.getColumn();
		if (column >= minColumn) {
			pos.setColumn(column);
		}
		if (jeu != null)
			jeu.update(this, null);
	}

	public void controlRight() {
		Position pos = personnage.getPosition();
		Dimension borders = parameters.getCharacterParameters()
				.getMovementBordersDimension();
		int column = pos.getColumn() + 1;
		int maxColumn = borders.getColumn() + borders.getWidth() - 1;
		if (column <= maxColumn) {
			pos.setColumn(column);
		}
		if (jeu != null)
			jeu.update(this, null);
	}

	public void controlUp() {
		Position pos = personnage.getPosition();
		Dimension borders = parameters.getCharacterParameters()
				.getMovementBordersDimension();
		int row = pos.getRow() - 1;
		int minRow = borders.getRow();
		if (row >= minRow) {
			pos.setRow(row);
		}
		if (jeu != null)
			jeu.update(this, null);
	}

	public void controlDown() {
		Position pos = personnage.getPosition();
		Dimension borders = parameters.getCharacterParameters()
				.getMovementBordersDimension();
		int row = pos.getRow() + 1;
		int maxRow = borders.getRow() + borders.getHeight() - 1;
		if (row <= maxRow) {
			pos.setRow(row);
		}
		if (jeu != null)
			jeu.update(this, null);
	}

	public void controlFire() {
		Sound actionSound = new Sound("res//son//action.wav");
		playSound(actionSound);
	}

	public void controlExit() {
		setFinished(true);
	}

	public void gameOver(boolean win) {
		if (win) {
			((Jeu) jeu).youWin();
		} else {
			((Jeu) jeu).gameOver();
		}
		setFinished(true);
	}

	public void tick() {

		// Gerer le comportement des enemies
		for (Objet enemy : objects) {
			actionsToCommit.put(enemy, new ArrayList<Action>());
			for (Behaviour comportement : parameters.getEnemyParametres()
					.getBehaviours()) {
				if (comportement.verifyConditions(this, enemy)) {
					actionsToCommit.get(enemy)
							.addAll(comportement.getActions());
				}
			}
		}

		// Gerer le comportement des personnages
		actionsToCommit.put(personnage, new ArrayList<Action>());
		for (Behaviour comportement : parameters.getCharacterParameters()
				.getBehaviours()) {
			if (comportement.verifyConditions(this, personnage)) {
				actionsToCommit.get(personnage).addAll(
						comportement.getActions());
			}
		}

		// Commit actions
		Set<Objet> objets = actionsToCommit.keySet();
		for (Objet key : objets) {
			ArrayList<Action> actions = actionsToCommit.get(key);
			for (Action act : actions) {
				act.commit(this, key);
			}
		}

		actionsToCommit.clear();

		// Generer enemy
		if (gameTimeMs % enemyAppearanceInterval == 0) {
			objects.add(parameters.getEnemyParametres().generateObject());
		}

		gameTimeMs += parameters.getDifficulty().getGameTickInterval() * 1000;
		Sound tickSound = parameters.getGameTickSound();
		playSound(tickSound);
	}

	private void playSound(Sound sound) {
		if (sound != null) {
			PlaySoundAction action = new PlaySoundAction(sound.getPath());
			action.commit(null, null);
		}
	}

	public GWParameters getParameters() {
		return parameters;
	}

	public Objet getPersonnage() {
		return personnage;
	}

	public ArrayList<Objet> getObjects() {
		return objects;
	}

	public Integer getScoreValue() {
		return scoreValue;
	}

	public Integer getDeathValue() {
		return deathValue;
	}

	public Boolean getFinished() {
		return finished;
	}

	public Boolean isFinished() {
		return finished;
	}

	public void setFinished(Boolean finished) {
		this.finished = finished;
	}

	public Observer getJeu() {
		return jeu;
	}

	public void incrementDeath() {
		deathValue = deathValue + 1;
	}

	public void incrementScore() {
		scoreValue = scoreValue + 1;

		long dec = (long) (parameters.getDifficulty()
				.getEnemyAppearanceIntervalDecrementation() * 1000);
		long tickInt = (long) (parameters.getDifficulty().getGameTickInterval() * 1000);
		if (tickInt - dec >= 200) {

		}
		if (enemyAppearanceInterval - dec >= tickInt * 3)
			enemyAppearanceInterval -= dec;
	}

	public void print() {
		System.out.println("Score: " + scoreValue + " Death: " + deathValue
				+ " Time: " + gameTimeMs);

		int rows = parameters.getGgrid().getRowsNumber();
		int cols = parameters.getGgrid().getColsNumber();
		Objet grid[][];
		grid = new Objet[rows][];
		for (int i = 0; i < rows; i++) {
			grid[i] = new Objet[cols];
			for (int j = 0; j < cols; j++)
				grid[i][j] = null;
		}

		int row = personnage.getPosition().getRow();
		int col = personnage.getPosition().getColumn();
		grid[row][col] = personnage;

		for (int i = 0; i < objects.size(); i++) {
			row = objects.get(i).getPosition().getRow();
			col = objects.get(i).getPosition().getColumn();
			grid[row][col] = objects.get(i);
		}

		for (int j = 0; j < cols + 1; j++) {
			System.out.print("--");
		}
		System.out.println();
		for (int i = 0; i < rows; i++) {
			System.out.print("|");
			for (int j = 0; j < cols; j++) {
				if (grid[i][j] != null) {
					System.out
							.print(grid[i][j].getRepresentation().getId(j, i));
				} else {
					System.out.print("  ");
				}
			}
			System.out.print("|");
			System.out.println();
		}
		for (int j = 0; j < cols + 1; j++) {
			System.out.print("--");
		}
		System.out.println();

	}

	public static void main(String[] args) throws InterruptedException {
		Thread gameThread = new Thread() {
			public void run() {

				GameState game = new GameState(generateTestGameParameters());

				game.init();

				while (!game.isFinished()) {

					game.print();

					// Game tick
					game.tick();

					// Delay
					try {
						sleep((long) (game.getParameters().getDifficulty()
								.getGameTickInterval() * 1000));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
		};
		gameThread.start();
		gameThread.join();
	}

	public static GWParameters generateTestGameParameters() {
		return generateVertGameFromParameters(7, 7, "", "", "Hero-Static.png",
				"Hero-Action.png", "Gobelin_Static.png", "Gobelin_Action.png",
				"attack.wav", "fall.wav", "win.wav", "gameOver.wav",
				"move.wav", "res//jeu2//sounds//", "res//jeu2//images//", 1.0,
				2.0, 0.5);
	}

	public static GWParameters generateGame1Parameters() {
		String pathSoundPreffix = "res//jeu1//sounds//";
		GWParameters params = new GWParameters();

		Grid ggrid = new Grid();
		ggrid.setColsNumber(5);
		ggrid.setRowsNumber(5);
		params.setGgrid(ggrid);

		// SGrid sgrid = new SGrid();
		// sgrid.setColsNumber(3);
		// sgrid.setRowsNumber(1);
		// params.setSgrid(sgrid);

		params.setGameTickSound(new Sound(pathSoundPreffix + "move.wav"));

		Difficulty dif = new Difficulty();
		dif.setGameTickInterval(0.5);
		dif.setEnemyAppearanceInterval(5.0);
		dif.setEnemyAppearanceIntervalDecrementation(1.0);
		params.setDifficulty(dif);

		HashMap<String, ObjectRepresentation> representations = new HashMap<String, ObjectRepresentation>();
		representations.put("01", new Sprite("01", 1, 4, "Hero-Static.png"));
		representations.put("02", new Sprite("02", 2, 4, "Hero-Static.png"));
		representations.put("03", new Sprite("03", 3, 4, "Hero-Static.png"));
		representations.put("04", new Sprite("04", "Hero-Static.png"));
		representations.put("06", new Sprite("06", "Gobelin1.png"));
		representations.put("07", new Sprite("07", "Gobelin2.png"));
		representations.put("08", new Sprite("08", "Gobelin3.png"));
		representations.put("09", new Sprite("09", "Gobelin4.png"));
		representations.put("10", new Sprite("10", "Gobelin5.png"));
		representations.put("11", new Sprite("11", "Gobelin6.png"));
		representations.put("12", new Sprite("12", "Gobelin7.png"));
		representations.put("13", new Sprite("13", "Gobelin8.png"));
		representations.put("14", new Sprite("14", "Gobelin_Die.png"));
		representations.put("15", new Sprite("15", "Gobelin_win.png"));
		representations.put("16", new Sprite("16", "Hero-Action.png"));
		params.setRepresentations(representations);

		SpriteSequence sequence0 = new SpriteSequence();
		sequence0.setId("00");
		sequence0.getSprites().add((Sprite) representations.get("01"));
		sequence0.getSprites().add((Sprite) representations.get("02"));
		sequence0.getSprites().add((Sprite) representations.get("03"));
		representations.put("00", sequence0);

		// Configuration de l'enemy
		CharacterParameters enemyParametres = new CharacterParameters();
		params.setEnemyParametres(enemyParametres);

		Position eInitialPos = new Position();
		eInitialPos.setColumn(3);
		eInitialPos.setRow(0);
		enemyParametres.setInitialPosition(eInitialPos);

		enemyParametres.setInitialRepresentation(representations.get("06"));

		Behaviour comp1 = new Behaviour();
		comp1.getConditions().add(new ScoreCondition(9));
		comp1.getActions().add(new GameOverAction(true));
		comp1.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "win.wav"));
		enemyParametres.getBehaviours().add(comp1);

		Behaviour comp2 = new Behaviour();
		comp2.getConditions().add(new DeathCondition(5));
		comp2.getActions().add(new GameOverAction(false));
		comp2.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "gameOver.wav"));
		enemyParametres.getBehaviours().add(comp2);

		Behaviour comp3 = new Behaviour();
		comp3.getConditions().add(new PositionCondition(3, 0));
		comp3.getConditions().add(new RepresentationCondition("06"));
		comp3.getActions().add(new MoveAction(3, 1));
		comp3.getActions().add(new ChangeRepresentationAction("07"));
		enemyParametres.getBehaviours().add(comp3);

		Behaviour comp4 = new Behaviour();
		comp4.getConditions().add(new PositionCondition(3, 1));
		comp4.getConditions().add(new RepresentationCondition("07"));
		comp4.getActions().add(new MoveAction(3, 2));
		comp4.getActions().add(new ChangeRepresentationAction("08"));
		enemyParametres.getBehaviours().add(comp4);

		Behaviour comp5 = new Behaviour();
		comp5.getConditions().add(new PositionCondition(3, 2));
		comp5.getConditions().add(new RepresentationCondition("08"));
		comp5.getActions().add(new MoveAction(3, 3));
		comp5.getActions().add(new ChangeRepresentationAction("09"));
		enemyParametres.getBehaviours().add(comp5);

		Behaviour comp6 = new Behaviour();
		comp6.getConditions().add(new PositionCondition(3, 3));
		comp6.getConditions().add(new RepresentationCondition("09"));
		comp6.getConditions().add(new CharacterTouchCondition());
		comp6.getActions().add(new MoveAction(3, 3));
		comp6.getActions().add(new ChangeRepresentationAction("10"));
		enemyParametres.getBehaviours().add(comp6);

		Behaviour comp7 = new Behaviour();
		comp7.getConditions().add(new PositionCondition(3, 3));
		comp7.getConditions().add(new RepresentationCondition("09"));
		comp7.getConditions().add(new CharacterTouchCondition(true));
		comp7.getActions().add(new MoveAction(3, 4));
		comp7.getActions().add(new ChangeRepresentationAction("14"));
		enemyParametres.getBehaviours().add(comp7);

		Behaviour comp8 = new Behaviour();
		comp8.getConditions().add(new PositionCondition(3, 3));
		comp8.getConditions().add(new RepresentationCondition("10"));
		comp8.getActions().add(new MoveAction(3, 2));
		comp8.getActions().add(new ChangeRepresentationAction("11"));
		enemyParametres.getBehaviours().add(comp8);

		Behaviour comp9 = new Behaviour();
		comp9.getConditions().add(new PositionCondition(3, 2));
		comp9.getConditions().add(new RepresentationCondition("11"));
		comp9.getActions().add(new MoveAction(3, 1));
		comp9.getActions().add(new ChangeRepresentationAction("12"));
		enemyParametres.getBehaviours().add(comp9);

		Behaviour comp10 = new Behaviour();
		comp10.getConditions().add(new PositionCondition(3, 1));
		comp10.getConditions().add(new RepresentationCondition("12"));
		comp10.getActions().add(new MoveAction(3, 0));
		comp10.getActions().add(new ChangeRepresentationAction("13"));
		enemyParametres.getBehaviours().add(comp10);

		Behaviour comp11 = new Behaviour();
		comp11.getConditions().add(new PositionCondition(3, 0));
		comp11.getConditions().add(new RepresentationCondition("13"));
		comp11.getActions().add(new MoveAction(2, 0));
		comp11.getActions().add(new ChangeRepresentationAction("06"));
		enemyParametres.getBehaviours().add(comp11);

		// ****
		Behaviour comp12 = new Behaviour();
		comp12.getConditions().add(new PositionCondition(2, 0));
		comp12.getConditions().add(new RepresentationCondition("06"));
		comp12.getActions().add(new MoveAction(2, 1));
		comp12.getActions().add(new ChangeRepresentationAction("07"));
		enemyParametres.getBehaviours().add(comp12);

		Behaviour comp13 = new Behaviour();
		comp13.getConditions().add(new PositionCondition(2, 1));
		comp13.getConditions().add(new RepresentationCondition("07"));
		comp13.getActions().add(new MoveAction(2, 2));
		comp13.getActions().add(new ChangeRepresentationAction("08"));
		enemyParametres.getBehaviours().add(comp13);

		Behaviour comp14 = new Behaviour();
		comp14.getConditions().add(new PositionCondition(2, 2));
		comp14.getConditions().add(new RepresentationCondition("08"));
		comp14.getActions().add(new MoveAction(2, 3));
		comp14.getActions().add(new ChangeRepresentationAction("09"));
		enemyParametres.getBehaviours().add(comp14);

		Behaviour comp15 = new Behaviour();
		comp15.getConditions().add(new PositionCondition(2, 3));
		comp15.getConditions().add(new RepresentationCondition("09"));
		comp15.getConditions().add(new CharacterTouchCondition());
		comp15.getActions().add(new MoveAction(2, 3));
		comp15.getActions().add(new ChangeRepresentationAction("10"));
		enemyParametres.getBehaviours().add(comp15);

		Behaviour comp16 = new Behaviour();
		comp16.getConditions().add(new PositionCondition(2, 3));
		comp16.getConditions().add(new RepresentationCondition("09"));
		comp16.getConditions().add(new CharacterTouchCondition(true));
		comp16.getActions().add(new MoveAction(2, 4));
		comp16.getActions().add(new ChangeRepresentationAction("14"));
		enemyParametres.getBehaviours().add(comp16);

		Behaviour comp17 = new Behaviour();
		comp17.getConditions().add(new RepresentationCondition("14"));
		comp17.getActions().add(new RemoveObjectAction());
		comp17.getActions().add(new IncrementDeathAction());
		comp17.getActions().add(
				new PlaySoundAction("res//jeu1//sounds//fall.wav"));
		enemyParametres.getBehaviours().add(comp17);

		Behaviour comp18 = new Behaviour();
		comp18.getConditions().add(new PositionCondition(2, 3));
		comp18.getConditions().add(new RepresentationCondition("10"));
		comp18.getActions().add(new MoveAction(2, 2));
		comp18.getActions().add(new ChangeRepresentationAction("11"));
		enemyParametres.getBehaviours().add(comp18);

		Behaviour comp19 = new Behaviour();
		comp19.getConditions().add(new PositionCondition(2, 2));
		comp19.getConditions().add(new RepresentationCondition("11"));
		comp19.getActions().add(new MoveAction(2, 1));
		comp19.getActions().add(new ChangeRepresentationAction("12"));
		enemyParametres.getBehaviours().add(comp19);

		Behaviour comp20 = new Behaviour();
		comp20.getConditions().add(new PositionCondition(2, 1));
		comp20.getConditions().add(new RepresentationCondition("12"));
		comp20.getActions().add(new MoveAction(2, 0));
		comp20.getActions().add(new ChangeRepresentationAction("13"));
		enemyParametres.getBehaviours().add(comp20);

		Behaviour comp21 = new Behaviour();
		comp21.getConditions().add(new PositionCondition(2, 0));
		comp21.getConditions().add(new RepresentationCondition("13"));
		comp21.getActions().add(new MoveAction(1, 0));
		comp21.getActions().add(new ChangeRepresentationAction("06"));
		enemyParametres.getBehaviours().add(comp21);

		// ****
		Behaviour comp22 = new Behaviour();
		comp22.getConditions().add(new PositionCondition(1, 0));
		comp22.getConditions().add(new RepresentationCondition("06"));
		comp22.getActions().add(new MoveAction(1, 1));
		comp22.getActions().add(new ChangeRepresentationAction("07"));
		enemyParametres.getBehaviours().add(comp22);

		Behaviour comp23 = new Behaviour();
		comp23.getConditions().add(new PositionCondition(1, 1));
		comp23.getConditions().add(new RepresentationCondition("07"));
		comp23.getActions().add(new MoveAction(1, 2));
		comp23.getActions().add(new ChangeRepresentationAction("08"));
		enemyParametres.getBehaviours().add(comp23);

		Behaviour comp24 = new Behaviour();
		comp24.getConditions().add(new PositionCondition(1, 2));
		comp24.getConditions().add(new RepresentationCondition("08"));
		comp24.getActions().add(new MoveAction(1, 3));
		comp24.getActions().add(new ChangeRepresentationAction("09"));
		enemyParametres.getBehaviours().add(comp24);

		Behaviour comp25 = new Behaviour();
		comp25.getConditions().add(new PositionCondition(1, 3));
		comp25.getConditions().add(new RepresentationCondition("09"));
		comp25.getConditions().add(new CharacterTouchCondition());
		comp25.getActions().add(new MoveAction(1, 3));
		comp25.getActions().add(new ChangeRepresentationAction("10"));
		enemyParametres.getBehaviours().add(comp25);

		Behaviour comp26 = new Behaviour();
		comp26.getConditions().add(new PositionCondition(1, 3));
		comp26.getConditions().add(new RepresentationCondition("09"));
		comp26.getConditions().add(new CharacterTouchCondition(true));
		comp26.getActions().add(new MoveAction(1, 4));
		comp26.getActions().add(new ChangeRepresentationAction("14"));
		enemyParametres.getBehaviours().add(comp26);

		Behaviour comp27 = new Behaviour();
		comp27.getConditions().add(new PositionCondition(1, 3));
		comp27.getConditions().add(new RepresentationCondition("10"));
		comp27.getActions().add(new MoveAction(1, 2));
		comp27.getActions().add(new ChangeRepresentationAction("11"));
		enemyParametres.getBehaviours().add(comp27);

		Behaviour comp28 = new Behaviour();
		comp28.getConditions().add(new PositionCondition(1, 2));
		comp28.getConditions().add(new RepresentationCondition("11"));
		comp28.getActions().add(new MoveAction(1, 1));
		comp28.getActions().add(new ChangeRepresentationAction("12"));
		enemyParametres.getBehaviours().add(comp28);

		Behaviour comp29 = new Behaviour();
		comp29.getConditions().add(new PositionCondition(1, 1));
		comp29.getConditions().add(new RepresentationCondition("12"));
		comp29.getActions().add(new MoveAction(1, 0));
		comp29.getActions().add(new ChangeRepresentationAction("13"));
		enemyParametres.getBehaviours().add(comp29);

		Behaviour comp30 = new Behaviour();
		comp30.getConditions().add(new PositionCondition(1, 0));
		comp30.getConditions().add(new RepresentationCondition("13"));
		comp30.getActions().add(new MoveAction(0, 0));
		comp30.getActions().add(new ChangeRepresentationAction("15"));
		enemyParametres.getBehaviours().add(comp30);

		Behaviour comp31 = new Behaviour();
		comp31.getConditions().add(new RepresentationCondition("15"));
		comp31.getActions().add(new RemoveObjectAction());
		comp31.getActions().add(new IncrementScoreAction());
		enemyParametres.getBehaviours().add(comp31);

		// Configuration du personnage
		CharacterParameters personnageParametres = new CharacterParameters();
		personnageParametres.setMovementBordersDimension(new Dimension(1, 4, 1,
				3));

		Position pInitialPos = new Position();
		pInitialPos.setColumn(3);
		pInitialPos.setRow(4);
		personnageParametres.setInitialPosition(pInitialPos);

		Behaviour compP5 = new Behaviour();
		compP5.getConditions().add(new CharacterTouchCondition());
		compP5.getActions().add(new ChangeRepresentationAction("16"));
		personnageParametres.getBehaviours().add(compP5);

		Behaviour compP6 = new Behaviour();
		compP6.getConditions().add(new CharacterTouchCondition(true));
		compP6.getConditions().add(new RepresentationCondition("16"));
		compP6.getActions().add(new ChangeRepresentationAction("01"));
		compP6.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "attack.wav"));
		personnageParametres.getBehaviours().add(compP6);

		personnageParametres
				.setInitialRepresentation(representations.get("01"));
		params.setCharacterParameters(personnageParametres);

		return params;
	}

	public static GWParameters generateGame2Parameters() {
		String pathSoundPreffix = "res//jeu2//sounds//";
		GWParameters params = new GWParameters();

		Grid ggrid = new Grid();
		ggrid.setColsNumber(5);
		ggrid.setRowsNumber(5);
		params.setGgrid(ggrid);

		// SGrid sgrid = new SGrid();
		// sgrid.setColsNumber(3);
		// sgrid.setRowsNumber(1);
		// params.setSgrid(sgrid);

		params.setGameTickSound(new Sound(pathSoundPreffix + "move.wav"));

		Difficulty dif = new Difficulty();
		dif.setGameTickInterval(0.5);
		dif.setEnemyAppearanceInterval(3.0);
		dif.setEnemyAppearanceIntervalDecrementation(1.0);
		params.setDifficulty(dif);

		HashMap<String, ObjectRepresentation> representations = new HashMap<String, ObjectRepresentation>();
		representations.put("01", new Sprite("01", "Hero-Static.png"));
		representations.put("02", new Sprite("02", "Hero-Action.png"));
		representations.put("03", new Sprite("03", "Gobelin_Action.png"));
		representations.put("04", new Sprite("04", "Gobelin_Static.png"));
		params.setRepresentations(representations);

		// Configuration de l'enemy
		CharacterParameters enemyParametres = new CharacterParameters();
		params.setEnemyParametres(enemyParametres);
		enemyParametres.setMovementBordersDimension(new Dimension(0, 0, 4, 5));

		Position eInitialPos = new Position();
		eInitialPos.setColumn(null);
		eInitialPos.setRow(0);
		enemyParametres.setInitialPosition(eInitialPos);

		enemyParametres.setInitialRepresentation(representations.get("04"));

		Behaviour comp1 = new Behaviour();
		comp1.getConditions().add(new ScoreCondition(9));
		comp1.getActions().add(new GameOverAction(true));
		comp1.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "win.wav"));
		enemyParametres.getBehaviours().add(comp1);

		Behaviour comp2 = new Behaviour();
		comp2.getConditions().add(new DeathCondition(5));
		comp2.getActions().add(new GameOverAction(false));
		comp2.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "gameOver.wav"));
		enemyParametres.getBehaviours().add(comp2);

		Behaviour comp27 = new Behaviour();
		comp27.getConditions().add(new PositionCondition(null, 0));
		comp27.getActions().add(new MoveAction(null, 1));
		enemyParametres.getBehaviours().add(comp27);

		Behaviour comp28 = new Behaviour();
		comp28.getConditions().add(new PositionCondition(null, 1));
		comp28.getActions().add(new MoveAction(null, 2));
		enemyParametres.getBehaviours().add(comp28);

		Behaviour comp29 = new Behaviour();
		comp29.getConditions().add(new PositionCondition(null, 2));
		comp29.getActions().add(new MoveAction(null, 3));
		enemyParametres.getBehaviours().add(comp29);

		Behaviour comp30 = new Behaviour();
		comp30.getConditions().add(new PositionCondition(null, 3));
		comp30.getConditions().add(new CharacterTouchCondition(true));
		comp30.getActions().add(new MoveAction(null, 4));
		enemyParametres.getBehaviours().add(comp30);

		Behaviour comp31 = new Behaviour();
		comp31.getConditions().add(new PositionCondition(null, 3));
		comp31.getConditions().add(new CharacterTouchCondition());
		comp31.getActions().add(new ChangeRepresentationAction("03"));
		enemyParametres.getBehaviours().add(comp31);

		Behaviour comp32 = new Behaviour();
		comp32.getConditions().add(new RepresentationCondition("03"));
		comp32.getActions().add(new RemoveObjectAction());
		comp32.getActions().add(new IncrementScoreAction());
		comp32.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "attack.wav"));
		enemyParametres.getBehaviours().add(comp32);

		Behaviour comp33 = new Behaviour();
		comp33.getConditions().add(new PositionCondition(null, 4));
		comp33.getActions().add(new RemoveObjectAction());
		comp33.getActions().add(new IncrementDeathAction());
		comp33.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "fall.wav"));
		enemyParametres.getBehaviours().add(comp33);

		// Configuration du personnage
		CharacterParameters personnageParametres = new CharacterParameters();
		personnageParametres.setMovementBordersDimension(new Dimension(0, 4, 1,
				5));

		Position pInitialPos = new Position();
		pInitialPos.setColumn(3);
		pInitialPos.setRow(4);
		personnageParametres.setInitialPosition(pInitialPos);

		Behaviour compP5 = new Behaviour();
		compP5.getConditions().add(new CharacterTouchCondition());
		compP5.getActions().add(new ChangeRepresentationAction("02"));
		personnageParametres.getBehaviours().add(compP5);

		Behaviour compP6 = new Behaviour();
		compP6.getConditions().add(new CharacterTouchCondition(true));
		compP6.getConditions().add(new RepresentationCondition("02"));
		compP6.getActions().add(new ChangeRepresentationAction("01"));
		compP6.getActions().add(
				new PlaySoundAction(pathSoundPreffix + "attack.wav"));
		personnageParametres.getBehaviours().add(compP6);

		personnageParametres
				.setInitialRepresentation(representations.get("01"));
		params.setCharacterParameters(personnageParametres);

		return params;
	}

	public static GWParameters generateVertGameFromParameters(int colonnes,
			int lignes, String fondDeJeu, String fondDappareil,
			String imageDePerso, String imageDePersoAct, String imageDeEnemy,
			String imageDeEnemyAct, String sonColision, String sonPertePoints,
			String sonGagne, String sonPerte, String sonMove,
			String pathSoundPreffix, String pathImagePreffix,
			Double gameTickInterval, Double enemyInterval,
			Double enemyIntervalDecrease) {
		GWParameters params = new GWParameters();

		params.setDeviceBackgroundPath(fondDappareil);
		params.setGridBackgroundPath(fondDeJeu);

		Grid ggrid = new Grid();
		ggrid.setColsNumber(colonnes);
		ggrid.setRowsNumber(lignes);
		params.setGgrid(ggrid);

		// SGrid sgrid = new SGrid();
		// sgrid.setColsNumber(3);
		// sgrid.setRowsNumber(1);
		// params.setSgrid(sgrid);

		params.setGameTickSound(new Sound(pathSoundPreffix + sonMove));

		Difficulty dif = new Difficulty();
		dif.setGameTickInterval(gameTickInterval);
		dif.setEnemyAppearanceInterval(enemyInterval);
		dif.setEnemyAppearanceIntervalDecrementation(enemyIntervalDecrease);
		params.setDifficulty(dif);

		HashMap<String, ObjectRepresentation> representations = new HashMap<String, ObjectRepresentation>();
		representations.put("01", new Sprite("01", imageDePerso));
		representations.put("02", new Sprite("02", imageDePersoAct));
		representations.put("03", new Sprite("03", imageDeEnemyAct));
		representations.put("04", new Sprite("04", imageDeEnemy));
		params.setRepresentations(representations);

		// Configuration de l'enemy
		CharacterParameters enemyParametres = new CharacterParameters();
		params.setEnemyParametres(enemyParametres);
		enemyParametres.setMovementBordersDimension(new Dimension(0, 0, lignes,
				colonnes));

		Position eInitialPos = new Position();
		eInitialPos.setColumn(null);
		eInitialPos.setRow(0);
		enemyParametres.setInitialPosition(eInitialPos);

		enemyParametres.setInitialRepresentation(representations.get("04"));

		Behaviour comp1 = new Behaviour();
		comp1.getConditions().add(new ScoreCondition(9));
		comp1.getActions().add(new GameOverAction(true));
		comp1.getActions()
				.add(new PlaySoundAction(pathSoundPreffix + sonGagne));
		enemyParametres.getBehaviours().add(comp1);

		Behaviour comp2 = new Behaviour();
		comp2.getConditions().add(new DeathCondition(5));
		comp2.getActions().add(new GameOverAction(false));
		comp2.getActions()
				.add(new PlaySoundAction(pathSoundPreffix + sonPerte));
		enemyParametres.getBehaviours().add(comp2);

		for (int i = 0; i < lignes - 2; i++) {
			Behaviour comp27 = new Behaviour();
			comp27.getConditions().add(new PositionCondition(null, i));
			comp27.getActions().add(new MoveAction(null, i + 1));
			enemyParametres.getBehaviours().add(comp27);
		}

		Behaviour comp30 = new Behaviour();
		comp30.getConditions().add(new PositionCondition(null, lignes - 2));
		comp30.getConditions().add(new CharacterTouchCondition(true));
		comp30.getActions().add(new MoveAction(null, lignes - 1));
		enemyParametres.getBehaviours().add(comp30);

		Behaviour comp31 = new Behaviour();
		comp31.getConditions().add(new PositionCondition(null, lignes - 2));
		comp31.getConditions().add(new CharacterTouchCondition());
		comp31.getActions().add(new ChangeRepresentationAction("03"));
		enemyParametres.getBehaviours().add(comp31);

		Behaviour comp32 = new Behaviour();
		comp32.getConditions().add(new RepresentationCondition("03"));
		comp32.getActions().add(new RemoveObjectAction());
		comp32.getActions().add(new IncrementScoreAction());
		comp32.getActions().add(
				new PlaySoundAction(pathSoundPreffix + sonColision));
		enemyParametres.getBehaviours().add(comp32);

		Behaviour comp33 = new Behaviour();
		comp33.getConditions().add(new PositionCondition(null, lignes - 1));
		comp33.getActions().add(new RemoveObjectAction());
		comp33.getActions().add(new IncrementDeathAction());
		comp33.getActions().add(
				new PlaySoundAction(pathSoundPreffix + sonPertePoints));
		enemyParametres.getBehaviours().add(comp33);

		// Configuration du personnage
		CharacterParameters personnageParametres = new CharacterParameters();
		personnageParametres.setMovementBordersDimension(new Dimension(0,
				lignes - 1, 1, colonnes));

		Position pInitialPos = new Position();
		pInitialPos.setColumn(null);
		pInitialPos.setRow(null);
		personnageParametres.setInitialPosition(pInitialPos);

		Behaviour compP5 = new Behaviour();
		compP5.getConditions().add(new CharacterTouchCondition());
		compP5.getActions().add(new ChangeRepresentationAction("02"));
		personnageParametres.getBehaviours().add(compP5);

		Behaviour compP6 = new Behaviour();
		compP6.getConditions().add(new CharacterTouchCondition(true));
		compP6.getConditions().add(new RepresentationCondition("02"));
		compP6.getActions().add(new ChangeRepresentationAction("01"));
		compP6.getActions().add(
				new PlaySoundAction(pathSoundPreffix + sonColision));
		personnageParametres.getBehaviours().add(compP6);

		personnageParametres
				.setInitialRepresentation(representations.get("01"));
		params.setCharacterParameters(personnageParametres);

		return params;
	}
	
	public static GWParameters generateHorGameFromParameters(int colonnes,
			int lignes, String fondDeJeu, String fondDappareil,
			String imageDePerso, String imageDePersoAct, String imageDeEnemy,
			String imageDeEnemyAct, String sonColision, String sonPertePoints,
			String sonGagne, String sonPerte, String sonMove,
			String pathSoundPreffix, String pathImagePreffix,
			Double gameTickInterval, Double enemyInterval,
			Double enemyIntervalDecrease) {
		GWParameters params = new GWParameters();

		params.setDeviceBackgroundPath(fondDappareil);
		params.setGridBackgroundPath(fondDeJeu);

		Grid ggrid = new Grid();
		ggrid.setColsNumber(colonnes);
		ggrid.setRowsNumber(lignes);
		params.setGgrid(ggrid);

		// SGrid sgrid = new SGrid();
		// sgrid.setColsNumber(3);
		// sgrid.setRowsNumber(1);
		// params.setSgrid(sgrid);

		params.setGameTickSound(new Sound(pathSoundPreffix + sonMove));

		Difficulty dif = new Difficulty();
		dif.setGameTickInterval(gameTickInterval);
		dif.setEnemyAppearanceInterval(enemyInterval);
		dif.setEnemyAppearanceIntervalDecrementation(enemyIntervalDecrease);
		params.setDifficulty(dif);

		HashMap<String, ObjectRepresentation> representations = new HashMap<String, ObjectRepresentation>();
		representations.put("01", new Sprite("01", imageDePerso));
		representations.put("02", new Sprite("02", imageDePersoAct));
		representations.put("03", new Sprite("03", imageDeEnemyAct));
		representations.put("04", new Sprite("04", imageDeEnemy));
		params.setRepresentations(representations);

		// Configuration de l'enemy
		CharacterParameters enemyParametres = new CharacterParameters();
		params.setEnemyParametres(enemyParametres);
		enemyParametres.setMovementBordersDimension(new Dimension(0, 0, lignes,
				colonnes));

		Position eInitialPos = new Position();
		eInitialPos.setColumn(0);
		eInitialPos.setRow(null);
		enemyParametres.setInitialPosition(eInitialPos);

		enemyParametres.setInitialRepresentation(representations.get("04"));

		Behaviour comp1 = new Behaviour();
		comp1.getConditions().add(new ScoreCondition(9));
		comp1.getActions().add(new GameOverAction(true));
		comp1.getActions()
				.add(new PlaySoundAction(pathSoundPreffix + sonGagne));
		enemyParametres.getBehaviours().add(comp1);

		Behaviour comp2 = new Behaviour();
		comp2.getConditions().add(new DeathCondition(5));
		comp2.getActions().add(new GameOverAction(false));
		comp2.getActions()
				.add(new PlaySoundAction(pathSoundPreffix + sonPerte));
		enemyParametres.getBehaviours().add(comp2);

		for (int i = 0; i < colonnes - 2; i++) {
			Behaviour comp27 = new Behaviour();
			comp27.getConditions().add(new PositionCondition(i, null));
			comp27.getActions().add(new MoveAction(i + 1, null));
			enemyParametres.getBehaviours().add(comp27);
		}

		Behaviour comp30 = new Behaviour();
		comp30.getConditions().add(new PositionCondition(colonnes - 2, null));
		comp30.getConditions().add(new CharacterTouchCondition(true));
		comp30.getActions().add(new MoveAction(colonnes - 1, null));
		enemyParametres.getBehaviours().add(comp30);

		Behaviour comp31 = new Behaviour();
		comp31.getConditions().add(new PositionCondition(colonnes - 2, null));
		comp31.getConditions().add(new CharacterTouchCondition());
		comp31.getActions().add(new ChangeRepresentationAction("03"));
		enemyParametres.getBehaviours().add(comp31);

		Behaviour comp32 = new Behaviour();
		comp32.getConditions().add(new RepresentationCondition("03"));
		comp32.getActions().add(new RemoveObjectAction());
		comp32.getActions().add(new IncrementScoreAction());
		comp32.getActions().add(
				new PlaySoundAction(pathSoundPreffix + sonColision));
		enemyParametres.getBehaviours().add(comp32);

		Behaviour comp33 = new Behaviour();
		comp33.getConditions().add(new PositionCondition(colonnes - 1, null));
		comp33.getActions().add(new RemoveObjectAction());
		comp33.getActions().add(new IncrementDeathAction());
		comp33.getActions().add(
				new PlaySoundAction(pathSoundPreffix + sonPertePoints));
		enemyParametres.getBehaviours().add(comp33);

		// Configuration du personnage
		CharacterParameters personnageParametres = new CharacterParameters();
		personnageParametres.setMovementBordersDimension(new Dimension(colonnes - 1,
				0, lignes, 1));

		Position pInitialPos = new Position();
		pInitialPos.setColumn(null);
		pInitialPos.setRow(null);
		personnageParametres.setInitialPosition(pInitialPos);

		Behaviour compP5 = new Behaviour();
		compP5.getConditions().add(new CharacterTouchCondition());
		compP5.getActions().add(new ChangeRepresentationAction("02"));
		personnageParametres.getBehaviours().add(compP5);

		Behaviour compP6 = new Behaviour();
		compP6.getConditions().add(new CharacterTouchCondition(true));
		compP6.getConditions().add(new RepresentationCondition("02"));
		compP6.getActions().add(new ChangeRepresentationAction("01"));
		compP6.getActions().add(
				new PlaySoundAction(pathSoundPreffix + sonColision));
		personnageParametres.getBehaviours().add(compP6);

		personnageParametres
				.setInitialRepresentation(representations.get("01"));
		params.setCharacterParameters(personnageParametres);

		return params;
	}

	public void setObservateurs(Observer jeu) {
		this.jeu = jeu;
	}

}
